Skip to content

fix(electron): disable service worker in desktop runtime#1066

Merged
4gray merged 1 commit into
masterfrom
fix/electron-disable-service-worker
Jun 14, 2026
Merged

fix(electron): disable service worker in desktop runtime#1066
4gray merged 1 commit into
masterfrom
fix/electron-disable-service-worker

Conversation

@4gray

@4gray 4gray commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Summary

  • Disable Angular service worker registration when the web bundle runs inside Electron or on a file: origin.
  • Clear legacy Electron service worker registrations and CacheStorage before loading the packaged renderer so existing desktop installs can recover after update.
  • Temporarily open DevTools by default in packaged Electron artifacts for white-screen diagnostics.
  • Keep the browser/PWA service worker path intact and document the Electron/PWA runtime boundary.

Changes

  • Add runtime checks for the Electron bridge and file: protocol before enabling ngsw-worker.js.
  • Clear Electron default-session serviceworkers and cachestorage before packaged loadFile.
  • Add regression tests for Electron/file service worker disabling, Electron custom-scheme coverage, cleanup ordering, cleanup failure fallback, and packaged DevTools diagnostics.
  • Document that packaged Electron must not register the Angular service worker and clears legacy desktop SW storage.

Testing

  • pnpm nx test electron-backend -- app.spec.ts --runInBand
  • pnpm nx test web -- runtime-config.spec.ts --runInBand
  • pnpm nx lint electron-backend --skipNxCache
  • pnpm nx lint web --skipNxCache
  • pnpm nx build electron-backend --configuration=production --skipNxCache
  • NX_TASKS_RUNNER_DYNAMIC_OUTPUT=false pnpm nx run electron-backend:make --prepackageOnly --platform=mac --arch=arm64 --skipNxCache
  • Packaged macOS smoke with agent-browser --cdp 9222: dashboard rendered, cleanup trace ran before renderer load, no service worker registration/controller/cache keys
  • git diff --check

Diagnostic Note

This PR currently opens DevTools by default in packaged Electron builds. Remove chore(electron): open devtools for packaged diagnostics before merging a normal release build.

@greptile-apps

greptile-apps Bot commented Jun 14, 2026

Copy link
Copy Markdown

Greptile Summary

This PR prevents Angular's ngsw-worker.js service worker from being registered when the web bundle runs inside Electron or from a file: origin, fixing a bug where stale file-origin SW caches in userData could serve old chunks after an Electron app update.

  • Adds ServiceWorkerRuntimeContext and getDefaultServiceWorkerRuntimeContext() to read window.electron and location.protocol, then gates shouldEnableServiceWorker on both being absent/non-file.
  • Adds two new unit tests covering the Electron-bridge and bare file: origin paths, and documents the Electron/PWA boundary in pwa-self-hosted.md.

Confidence Score: 4/5

Safe to merge with awareness that users upgrading from a version that already registered a file-origin SW will not have it automatically cleaned up by this change alone.

The runtime guards and test coverage are correct for all new registrations. The gap is that provideServiceWorker(enabled: false) does not unregister a service worker that was previously installed under a file: origin in an earlier Electron build — affected users would still have a stale SW in control after updating until it is explicitly removed.

apps/web/src/app/services/runtime-config.ts — the new shouldEnableServiceWorker guards are correct, but the call site in app.config.ts has no companion unregistration logic for existing stale SW registrations.

Important Files Changed

Filename Overview
apps/web/src/app/services/runtime-config.ts Adds ServiceWorkerRuntimeContext, a default context reader from globalThis.window, and two new guards (!electronBridge, protocol !== 'file:') in shouldEnableServiceWorker. Logic is correct; no cleanup for existing stale registrations.
apps/web/src/app/services/runtime-config.spec.ts Adds two well-structured tests for Electron runtime and file-origin SW disabling; the existing "enables SW" test now implicitly relies on the default context getter returning non-Electron, non-file values from jsdom.
docs/architecture/pwa-self-hosted.md Adds a short explanatory paragraph documenting why the Angular service worker must not be registered in the Electron desktop runtime.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[App startup\napp.config.ts] --> B[shouldEnableServiceWorker]
    B --> C{production?}
    C -- No --> Z[SW disabled]
    C -- Yes --> D{navigator has\nserviceWorker?}
    D -- No --> Z
    D -- Yes --> E{electronBridge\npresent?}
    E -- Yes --> Z
    E -- No --> F{protocol === 'file:'?}
    F -- Yes --> Z
    F -- No --> G[SW enabled\nngsw-worker.js registered]

    subgraph getDefaultServiceWorkerRuntimeContext
        H[globalThis.window?.electron] --> I[electronBridge]
        J[window?.location?.protocol\n?? globalThis.location?.protocol] --> K[protocol]
    end
Loading

Reviews (2): Last reviewed commit: "fix(electron): disable service worker in..." | Re-trigger Greptile

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0ed2a71c7e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +48 to +49
!runtimeContext.electronBridge &&
runtimeContext.protocol !== 'file:'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Clear existing Electron service workers before disabling registration

When a user upgrades from a desktop version that already registered ngsw-worker.js, returning false here only prevents this version's Angular initializer from registering again; it does not unregister an active registration or clear NGSW caches. The old file-origin worker can control the first file:// navigation and serve the previous index.html/chunks before this new runtime check ever runs, so affected Electron installs can remain pinned to stale UI until userData is cleared. Add cleanup from the Electron main/session side, or an enabled renderer cleanup path, for existing registrations/caches.

Useful? React with 👍 / 👎.

Comment on lines +40 to +51
it('disables service worker for Electron runtime', () => {
expect(
shouldEnableServiceWorker(
true,
{ serviceWorker: {} } as Navigator,
{
electronBridge: {},
protocol: 'file:',
}
)
).toBe(false);
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing coverage: electronBridge-only guard

The Electron test always supplies both electronBridge and protocol: 'file:', so neither condition is ever isolated. If an Electron build ever uses a non-file: scheme (e.g. app:// or a custom iptvnator:// protocol), the only guard that fires is !electronBridge, but no test exercises that path. Adding a case where electronBridge is set and protocol is 'https:' (or any non-file: value) would pin that contract.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/src/app/services/runtime-config.spec.ts
Line: 40-51

Comment:
**Missing coverage: `electronBridge`-only guard**

The Electron test always supplies both `electronBridge` and `protocol: 'file:'`, so neither condition is ever isolated. If an Electron build ever uses a non-`file:` scheme (e.g. `app://` or a custom `iptvnator://` protocol), the only guard that fires is `!electronBridge`, but no test exercises that path. Adding a case where `electronBridge` is set and `protocol` is `'https:'` (or any non-`file:` value) would pin that contract.

How can I resolve this? If you propose a fix, please make it concise.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@4gray

4gray commented Jun 14, 2026

Copy link
Copy Markdown
Owner Author

@greptileai

@4gray
4gray force-pushed the fix/electron-disable-service-worker branch 2 times, most recently from bbd54c6 to ce78669 Compare June 14, 2026 15:30
@4gray
4gray merged commit cfd6f7f into master Jun 14, 2026
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant